AVL平衡二叉树的各种问题(Balanced Binary Tree)
AVL树或者是一棵空树,或者是具有以下性质的非空二叉搜索树:
1. 任一结点的左、右子树均为AVL树;
2.根结点左、右子树高度差的绝对值不超过1.
1.声明
#include<iostream> #include<cstdio> #include<queue> using namespace std; typedef int ElementType; typedef struct AVLNode * AVLTree; //AVL树类型 struct AVLNode{ ElementType Data; //结点数据 AVLTree Left; //左子树 AVLTree Right; //右子树 int Height; //树高 };
2.获取高度
int GetHeight(AVLTree T){ if(T) return max(GetHeight(T->Left ),GetHeight(T->Right )) + 1; else return 0; }
3.左单旋LL
AVLTree SingleLeftRotation(AVLTree A){ // 注意:A 必须有一个左子结点 B // 将 A 与 B 左单选,更新 A 与 B 的高度,返回新的根结点 B AVLTree B = A->Left ; A->Left = B->Right ; B->Right = A; A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1; B->Height = max(GetHeight(B->Left ),A->Height ) + 1; return B; }
4.右单旋RR
AVLTree SingleRightRotation(AVLTree A){ AVLTree B = A->Right ; A->Right = B->Left ; B->Left = A; A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1; B->Height = max(GetHeight(B->Right ),A->Height ) + 1; return B; }
5.左-右双旋LR
AVLTree DoubleLeftRightRotation(AVLTree A){ // 注意:A必须有一个左子结点 B,且 B必须有一个右子结点 C // 将 A、B 与 C 做两次单旋,返回新的根结点 C //将 B 与 C 做右单旋,C被返回 A->Left = SingleRightRotation(A->Left ); //将 A 与 C 做左单旋,C被返回 return SingleLeftRotation(A); }
6.右-左双旋RL
AVLTree DoubleRightLeftRotation(AVLTree A){ A->Right = SingleLeftRotation(A->Right ); return SingleRightRotation(A); }
7.AVL树的插入
AVLTree Insert(AVLTree T, ElementType X){ //将 X 插入AVL树 T 中,并且返回调整后的AVL树 if(! T){ //若插入空树,则新建包含一个结点的树 T = (AVLTree)malloc(sizeof(struct AVLNode)); T->Data = X; T->Height = 1; T->Left = T->Right = NULL; } else if(X < T->Data ){ // 插入 T 的左子树 T->Left =Insert(T->Left , X); // 如果需要左旋 if(GetHeight(T->Left ) - GetHeight(T->Right )== 2) if(X <T->Left ->Data) T = SingleLeftRotation(T); //左单旋 else T = DoubleLeftRightRotation(T); //左-右双旋 } else if(X > T->Data ){ // 插入 T 的右子树 T->Right = Insert(T->Right , X); // 如果需要右旋 if(GetHeight(T->Left ) - GetHeight(T->Right )== -2) if(X > T->Right ->Data) T = SingleRightRotation(T); //右单选 else T = DoubleRightLeftRotation(T); //右-左双旋 } // else X==T->Data 无需插入 //更新树高 T->Height = max(GetHeight(T->Left ),GetHeight(T->Right )) + 1; return T; }
完整测试:
#include<iostream> #include<cstdio> #include<queue> using namespace std; typedef int ElementType; typedef struct AVLNode * AVLTree; struct AVLNode{ ElementType Data; AVLTree Left; AVLTree Right; int Height; }; int GetHeight(AVLTree T){ if(T) return max(GetHeight(T->Left ),GetHeight(T->Right )) + 1; else return 0; } AVLTree SingleLeftRotation(AVLTree A){ AVLTree B = A->Left ; A->Left = B->Right ; B->Right = A; A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1; B->Height = max(GetHeight(B->Left ),A->Height ) + 1; return B; } AVLTree SingleRightRotation(AVLTree A){ AVLTree B = A->Right ; A->Right = B->Left ; B->Left = A; A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1; B->Height = max(GetHeight(B->Right ),A->Height ) + 1; return B; } AVLTree DoubleLeftRightRotation(AVLTree A){ A->Left = SingleRightRotation(A->Left ); return SingleLeftRotation(A); } AVLTree DoubleRightLeftRotation(AVLTree A){ A->Right = SingleLeftRotation(A->Right ); return SingleRightRotation(A); } AVLTree Insert(AVLTree T, ElementType X){ if(! T){ T = (AVLTree)malloc(sizeof(struct AVLNode)); T->Data = X; T->Height = 1; T->Left = T->Right = NULL; } else if(X < T->Data ){ T->Left =Insert(T->Left , X); if(GetHeight(T->Left ) - GetHeight(T->Right )== 2) if(X <T->Left ->Data) T = SingleLeftRotation(T); else T = DoubleLeftRightRotation(T); } else if(X > T->Data ){ T->Right = Insert(T->Right , X); if(GetHeight(T->Left ) - GetHeight(T->Right )== -2) if(X > T->Right ->Data) T = SingleRightRotation(T); else T = DoubleRightLeftRotation(T); } T->Height = max(GetHeight(T->Left ),GetHeight(T->Right )) + 1; return T; } void LevelorderTravelsal(AVLTree BT){ queue<AVLTree> q; AVLTree T; if(!BT) return; q.push(BT); while(!q.empty()){ T=q.front(); q.pop(); cout<<T->Data <<" "; if(T->Left ) q.push(T->Left ); if(T->Right ) q.push(T->Right ); } } int main(){ int n; cin>>n; AVLTree T = NULL; for(int i=0;i<n;i++){ int x; cin>>x; T = Insert(T, x); } LevelorderTravelsal(T); }
人生不如意的时候,是上帝给的长假,这个时候应该好好享受假期。
突然有一天假期结束,时来运转,人生才是真正开始了。
突然有一天假期结束,时来运转,人生才是真正开始了。